home *** CD-ROM | disk | FTP | other *** search
/ Creating Your Own America Online Web Pages / Creating Your Own America Online Web Pages.iso / TOOLS / TEX2RTF / SOURCES.ZIP / SRC / WXWIN / WB_UTILS.CC < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-05  |  13.9 KB  |  713 lines

  1. /*
  2.  * File:     wb_utils.cc
  3.  * Purpose:  Miscellaneous utilities
  4.  *
  5.  *                       wxWindows 1.50
  6.  * Copyright (c) 1993 Artificial Intelligence Applications Institute,
  7.  *                   The University of Edinburgh
  8.  *
  9.  *                     Author: Julian Smart
  10.  *                       Date: 7-9-93
  11.  *
  12.  * Permission to use, copy, modify, and distribute this software and its
  13.  * documentation for any purpose is hereby granted without fee, provided
  14.  * that the above copyright notice, author statement and this permission
  15.  * notice appear in all copies of this software and related documentation.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS,
  18.  * IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
  19.  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  20.  *
  21.  * IN NO EVENT SHALL THE ARTIFICIAL INTELLIGENCE APPLICATIONS INSTITUTE OR THE
  22.  * UNIVERSITY OF EDINBURGH BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR
  23.  * CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM
  24.  * LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF
  25.  * DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH
  26.  * THE USE OR PERFORMANCE OF THIS SOFTWARE.
  27.  */
  28.  
  29.  
  30. #include "common.h"
  31. #include "wx_utils.h"
  32. #include "wx_list.h"
  33.  
  34. #include <iostream.h>
  35. #include <fstream.h>
  36. #include <ctype.h>
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <errno.h>
  41.  
  42. // Useful buffer
  43. char wxBuffer[500];
  44.  
  45. char *copystring(char *s)
  46. {
  47.   int l = strlen(s);
  48.   char *news = new char[l+1];
  49.   strcpy(news, s);
  50.   return news;
  51. }
  52.  
  53. // Id generation
  54. static long wxCurrentId = 100;
  55. long NewId(void)
  56. {
  57.   return wxCurrentId++;
  58. }
  59.  
  60. void RegisterId(long id)
  61. {
  62.   if (id >= wxCurrentId)
  63.     wxCurrentId = id + 1;
  64. }
  65.  
  66.  
  67. void StringToFloat(char *s, float *number)
  68. {
  69.   if (s && strlen(s) > 0)
  70.   {
  71.     double n = strtod(s, NULL);
  72.     *number = (float)n;
  73.   }
  74. }
  75.  
  76. void StringToDouble(char *s, double *number)
  77. {
  78.   if (s && strlen(s) > 0)
  79.   {
  80.     *number = strtod(s, NULL);
  81.   }
  82. }
  83.  
  84. char *FloatToString(float number)
  85. {
  86.   char buf[80];
  87.   sprintf(buf, "%.2f", number);
  88.   return copystring(buf);
  89. }
  90.  
  91. char *DoubleToString(double number)
  92. {
  93.   char buf[80];
  94.   sprintf(buf, "%.2lf", number);
  95.   return copystring(buf);
  96. }
  97.  
  98. void StringToInt(char *s, int *number)
  99. {
  100.   if (s && strlen(s) > 0)
  101.   {
  102.     long n = strtol(s, NULL, 10);
  103.     *number = (int)n;
  104.   }
  105. }
  106.  
  107. void StringToLong(char *s, long *number)
  108. {
  109.   if (s && strlen(s) > 0)
  110.   {
  111.     *number = strtol(s, NULL, 10);
  112.   }
  113. }
  114.  
  115. char *IntToString(int number)
  116. {
  117.   char buf[80];
  118.   sprintf(buf, "%d", number);
  119.   return copystring(buf);
  120. }
  121.  
  122. char *LongToString(long number)
  123. {
  124.   char buf[80];
  125.   sprintf(buf, "%ld", number);
  126.   return copystring(buf);
  127. }
  128.  
  129. // Match a string (one) within a string (two)
  130. Bool StringMatch(char *one, char *two, Bool subString, Bool exact)
  131. {
  132.   int lenOne = strlen(one);
  133.   int lenTwo = strlen(two);
  134.  
  135.   char *oneUpper = new char[lenOne + 1];
  136.   char *twoUpper = new char[lenTwo + 1];
  137.  
  138.   int j = 0;
  139.   for (j = 0; j < lenOne; j++)
  140.     oneUpper[j] = toupper(one[j]);
  141.   oneUpper[j] = 0;
  142.  
  143.   for (j = 0; j < lenTwo; j++)
  144.     twoUpper[j] = toupper(two[j]);
  145.   twoUpper[j] = 0;
  146.   
  147.   int found = FALSE;
  148.   if (subString)
  149.   {
  150.     int i = 0;
  151.     while (!found && i < lenTwo)
  152.     {
  153.       strncpy(wxBuffer, twoUpper + i, lenOne);
  154.       wxBuffer[lenOne] = 0;
  155.       if (strcmp(oneUpper, wxBuffer) == 0)
  156.         found = TRUE;
  157.       i ++;
  158.     }
  159.   }
  160.   else
  161.   {
  162.     if (exact)
  163.       found = (strcmp(oneUpper, twoUpper) == 0);
  164.     else
  165.       found = (strncmp(oneUpper, twoUpper, min(lenOne, lenTwo)) == 0);
  166.   }
  167.  
  168.   delete[] oneUpper;
  169.   delete[] twoUpper;
  170.  
  171.   return found;
  172. }
  173.  
  174.  
  175. /****** FILE UTILITIES ******/
  176.  
  177. void wxPathList::Add(char *path)
  178. {
  179.   Append((wxObject *)path);
  180. }
  181.  
  182. // Add paths e.g. from the PATH environment variable
  183. void wxPathList::AddEnvList(char *envVariable)
  184. {
  185.   char *val = getenv(envVariable);
  186.   if (val)
  187.   {
  188.     char *s = copystring(val);
  189. #if (defined(wx_msw) || defined(wx_dos))
  190.     char *token = strtok(s, " ;"); // Don't seperate with colon in DOS as this may be
  191.                                    // part of a drive specification.
  192. #else
  193.     char *token = strtok(s, " :;");
  194. #endif
  195.  
  196.     if (token)
  197.     {
  198.       Add(copystring(token));
  199.       while (token)
  200.       {
  201. #if (defined(wx_msw) || defined(wx_dos))
  202.         token = strtok(NULL, " ;");
  203. #else
  204.         token = strtok(NULL, " :;");
  205. #endif
  206.         if (token)
  207.           Add(copystring(token));
  208.       }
  209.     }
  210.   }
  211. }
  212.  
  213. // Given a full filename (with path), ensure that that file can
  214. // be accessed again USING FILENAME ONLY by adding the path
  215. // to the list if not already there.
  216. void wxPathList::EnsureFileAccessible(char *path)
  217. {
  218.   char *path_only = PathOnly(path);
  219.   if (path_only)
  220.   {
  221.     if (!Member(path_only))
  222.       Add(path_only);
  223.     else delete[] path_only;
  224.   }
  225. }
  226.  
  227. Bool wxPathList::Member(char *path)
  228. {
  229.   char *pathcopy = copystring(path);
  230.   int i;
  231.   int len = strlen(pathcopy);
  232.   for (i = 0; i < len; i++)
  233.     pathcopy[i] = toupper(pathcopy[i]);
  234.  
  235.   wxNode *node = First();
  236.   Bool found = FALSE;
  237.   while (node && !found)
  238.   {
  239.     char *path = (char *)node->Data();
  240.     
  241.     strcpy(wxBuffer, path);
  242.  
  243.     len = strlen(wxBuffer);
  244.     for (i = 0; i < len; i++)
  245.       wxBuffer[i] = toupper(wxBuffer[i]);
  246.  
  247.     if (strcmp(pathcopy, wxBuffer) == 0)
  248.     {
  249.       found = TRUE;
  250.       node = NULL;
  251.     }
  252.     else node = node->Next();
  253.   }
  254.   delete[] pathcopy;
  255.   return found;
  256. }
  257.  
  258. char *wxPathList::FindValidPath(char *file)
  259. {
  260.   if (FileExists(file))
  261.     return file;
  262.  
  263.   char *filename;
  264.  
  265.   if (IsAbsolutePath(file))
  266.     filename = FileNameFromPath(file);
  267.   else
  268.     filename = copystring(file);
  269.  
  270.   wxNode *node = First();
  271.   char *found = NULL;
  272.   while (node && !found)
  273.   {
  274.     char *path = (char *)node->Data();
  275.     strcpy(wxBuffer, path);
  276. #ifdef wx_x
  277.     strcat(wxBuffer, "/");
  278. #endif
  279. #if (defined(wx_msw) || defined(wx_dos))
  280.     strcat(wxBuffer, "\\");
  281. #endif
  282.     strcat(wxBuffer, filename);
  283. #if (defined(wx_msw) || defined(wx_dos))
  284.     Unix2DosFilename(wxBuffer);
  285. #endif
  286.     if (FileExists(wxBuffer))
  287.     {
  288.       found = wxBuffer;
  289.     }
  290.     else
  291.       node = node->Next();
  292.   }
  293.   delete[] filename;
  294.   return found;
  295. }
  296.  
  297. Bool FileExists(char *filename)
  298. {
  299.   if (!filename)
  300.     return FALSE;
  301.   FILE *fd = fopen(filename, "r");
  302.   Bool bad = (fd == NULL);
  303.   if (fd)
  304.     fclose(fd);
  305.  
  306.   return !bad;
  307. }
  308.  
  309. Bool IsAbsolutePath(char *filename)
  310. {
  311.   int len = strlen(filename);
  312.   if ((len > 0 && (filename[0] == '/' || filename[0] == '\\')) ||
  313.       (len > 1 && (filename[1] == ':')))
  314.     return TRUE;
  315.   else
  316.     return FALSE;
  317. }
  318.  
  319. // Return just the filename, not the path
  320. char *FileNameFromPath(char *path)
  321. {
  322.   if (!path)
  323.     return NULL;
  324.  
  325.   char buf[200];
  326.   int i = 0;
  327.   int l = strlen(path);
  328.   Bool done = FALSE;
  329.  
  330.   i = l - 1;
  331.  
  332.   // Search backward for a backward or forward slash
  333.   while (!done && i > -1)
  334.   {
  335.     if (path[i] == '/' || path[i] == '\\')
  336.     {
  337.       done = TRUE;
  338.     }
  339.     else i --;
  340.   }
  341.   i ++;
  342.  
  343.   int j;
  344.   for (j = i; j < l; j++)
  345.   {
  346.     buf[j - i] = path[j];
  347.   }
  348.   buf[j - i] = 0;
  349.   return copystring(buf);
  350. }
  351.  
  352. // Return just the directory, or NULL if no directort
  353. char *PathOnly(char *path)
  354. {
  355.   if (!path)
  356.     return NULL;
  357.  
  358.   char buf[200];
  359.   strcpy(buf, path);
  360.  
  361.   int i = 0;
  362.   int l = strlen(path);
  363.   Bool done = FALSE;
  364.  
  365.   i = l - 1;
  366.  
  367.   // Search backward for a backward or forward slash
  368.   while (!done && i > -1)
  369.   {
  370.     if (path[i] == '/' || path[i] == '\\')
  371.     {
  372.       done = TRUE;
  373.     }
  374.     else i --;
  375.   }
  376.  
  377.   if (i >= 0)
  378.     buf[i] = 0;
  379.   else
  380.     buf[0] = 0;
  381.  
  382.   if (i <= 0)
  383.     return NULL;
  384.   else
  385.     return copystring(buf);
  386. }
  387.  
  388. // Utility for converting delimiters in DOS filenames to UNIX style
  389. // and back again - or we get nasty problems with delimiters
  390.  
  391. void Dos2UnixFilename(char *s)
  392. {
  393.   int l = strlen(s);
  394.   int i;
  395.   for (i = 0; i < l; i++)
  396.     if (s[i] == '\\')
  397.       s[i] = '/';
  398. }
  399.  
  400. void Unix2DosFilename(char *s)
  401. {
  402. #if (defined(wx_msw) || defined(wx_dos))
  403.   int l = strlen(s);
  404.   int i;
  405.   for (i = 0; i < l; i++)
  406.     if (s[i] == '/')
  407.       s[i] = '\\';
  408. #endif
  409. }
  410.  
  411. /*
  412.  * Check whether the filename has wildcards
  413.  *
  414.  */
  415.  
  416. Bool wxIsWild(char *pattern)
  417. {
  418.   register char *p = pattern;
  419.   register char c;
  420.  
  421.   while ((c = *p++) != '\0')
  422.     switch (c)
  423.       {
  424.       case '?':
  425.       case '[':
  426.       case '*':
  427.     return TRUE;
  428.  
  429.       case '\\':
  430.     if (*p++ == '\0')
  431.       return FALSE;
  432.       }
  433.  
  434.   return FALSE;
  435. }
  436.  
  437. /* Match the pattern PATTERN against the string TEXT;
  438.    return 1 if it matches, 0 otherwise.
  439.  
  440.    A match means the entire string TEXT is used up in matching.
  441.  
  442.    In the pattern string, `*' matches any sequence of characters,
  443.    `?' matches any character, [SET] matches any character in the specified set,
  444.    [!SET] matches any character not in the specified set.
  445.  
  446.    A set is composed of characters or ranges; a range looks like
  447.    character hyphen character (as in 0-9 or A-Z).
  448.    [0-9a-zA-Z_] is the set of characters allowed in C identifiers.
  449.    Any other character in the pattern must be matched exactly.
  450.  
  451.    To suppress the special syntactic significance of any of `[]*?!-\',
  452.    and match the character exactly, precede it with a `\'.
  453.  
  454.    If DOT_SPECIAL is nonzero,
  455.    `*' and `?' do not match `.' at the beginning of TEXT.
  456.  
  457.    THESE ROUTINES TAKEN FROM GLOB.C IN THE GNU LIBRARY. SEE GNU LICENSE.
  458.  */
  459.  
  460. static int
  461. wx_glob_match_after_star (char *pattern, char *text);
  462.  
  463. Bool wxMatchWild(char *pattern, char *text, Bool dot_special)
  464. {
  465.   register char *p = pattern, *t = text;
  466.   register char c;
  467.  
  468.   while ((c = *p++) != '\0')
  469.     switch (c)
  470.       {
  471.       case '?':
  472.     if (*t == '\0' || (dot_special && t == text && *t == '.'))
  473.       return 0;
  474.     else
  475.       ++t;
  476.     break;
  477.  
  478.       case '\\':
  479.     if (*p++ != *t++)
  480.       return 0;
  481.     break;
  482.  
  483.       case '*':
  484.     if (dot_special && t == text && *t == '.')
  485.       return 0;
  486.     return wx_glob_match_after_star (p, t);
  487.  
  488.       case '[':
  489.     {
  490.       register char c1 = *t++;
  491.       int invert;
  492.  
  493.       if (c1 == '\0')
  494.         return 0;
  495.  
  496.       invert = (*p == '!');
  497.  
  498.       if (invert)
  499.         p++;
  500.  
  501.       c = *p++;
  502.       while (1)
  503.         {
  504.           register char cstart = c, cend = c;
  505.  
  506.           if (c == '\\')
  507.         {
  508.           cstart = *p++;
  509.           cend = cstart;
  510.         }
  511.  
  512.           if (cstart == '\0')
  513.         return 0;    /* Missing ']'. */
  514.  
  515.           c = *p++;
  516.  
  517.           if (c == '-')
  518.         {
  519.           cend = *p++;
  520.           if (cend == '\\')
  521.             cend = *p++;
  522.           if (cend == '\0')
  523.             return 0;
  524.           c = *p++;
  525.         }
  526.           if (c1 >= cstart && c1 <= cend)
  527.         goto match;
  528.           if (c == ']')
  529.         break;
  530.         }
  531.       if (!invert)
  532.         return 0;
  533.       break;
  534.  
  535.     match:
  536.       /* Skip the rest of the [...] construct that already matched.  */
  537.       while (c != ']')
  538.         {
  539.           if (c == '\0')
  540.         return 0;
  541.           c = *p++;
  542.           if (c == '\0')
  543.         return 0;
  544.           if (c == '\\')
  545.         p++;
  546.         }
  547.       if (invert)
  548.         return 0;
  549.       break;
  550.     }
  551.  
  552.       default:
  553.     if (c != *t++)
  554.       return 0;
  555.       }
  556.  
  557.   return *t == '\0';
  558. }
  559.  
  560. /* Like glob_match, but match PATTERN against any final segment of TEXT.  */
  561.  
  562. static Bool
  563. wx_glob_match_after_star (char *pattern, char *text)
  564. {
  565.   register char *p = pattern, *t = text;
  566.   register char c, c1;
  567.  
  568.   while ((c = *p++) == '?' || c == '*')
  569.     if (c == '?' && *t++ == '\0')
  570.       return 0;
  571.  
  572.   if (c == '\0')
  573.     return 1;
  574.  
  575.   if (c == '\\')
  576.     c1 = *p;
  577.   else
  578.     c1 = c;
  579.  
  580.   --p;
  581.   while (1)
  582.     {
  583.       if ((c == '[' || *t == c1) && wxMatchWild (p, t, 0))
  584.     return 1;
  585.       if (*t++ == '\0')
  586.     return 0;
  587.     }
  588. }
  589.  
  590. // Concatenate two files to form third
  591. Bool wxConcatFiles(char *file1, char *file2, char *file3)
  592. {
  593.   FILE *fd1 = fopen(file1, "rb");
  594.   FILE *fd2 = fopen(file2, "rb");
  595.   FILE *fd3 = fopen(file3, "wb");
  596.  
  597.   if (!(fd1 && fd2 && fd3))
  598.     return FALSE;
  599.  
  600.   int ch = -2;
  601.   while (ch != EOF)
  602.   {
  603.     ch = getc(fd1);
  604.     if (ch != EOF)
  605.       putc(ch, fd3);
  606.   }
  607.   ch = -2;
  608.   while (ch != EOF)
  609.   {
  610.     ch = getc(fd2);
  611.     if (ch != EOF)
  612.       putc(ch, fd3);
  613.   }
  614.   fclose(fd1);
  615.   fclose(fd2);
  616.   fclose(fd3);
  617.  
  618.   return TRUE;
  619. }
  620.  
  621. // Copy files
  622. Bool wxCopyFile(char *file1, char *file2)
  623. {
  624.   FILE *fd1 = fopen(file1, "rb");
  625.   FILE *fd2 = fopen(file2, "wb");
  626.  
  627.   if (!(fd1 && fd2))
  628.     return FALSE;
  629.  
  630.   int ch = -2;
  631.   while (ch != EOF)
  632.   {
  633.     ch = getc(fd1);
  634.     if (ch != EOF)
  635.       putc(ch, fd2);
  636.   }
  637.   fclose(fd1);
  638.   fclose(fd2);
  639.   return TRUE;
  640. }
  641.  
  642. Bool wxRenameFile(char *file1, char *file2)
  643. {
  644.   int flag = rename(file1, file2);
  645.   if (flag == 0) return TRUE;
  646.   return FALSE;
  647. }
  648.  
  649. Bool wxRemoveFile(char *file)
  650. {
  651. #ifdef wx_x
  652.   int flag = unlink(file);
  653. #endif
  654. #ifdef wx_dos
  655.   int flag = remove(file);
  656. #endif
  657.   if (flag == 0) return TRUE;
  658.   return FALSE;
  659. }
  660.  
  661. // Get a temporary filename, opening and closing the file.
  662. /*
  663. void wxGetTempFileName(char *prefix, char *buf)
  664. {
  665.   ::GetTempFileName(0, prefix, 0, buf);
  666. }
  667.  
  668. // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
  669. long wxGetFreeMemory(void)
  670. {
  671.   return (long)GetFreeSpace(0);
  672. }
  673.  
  674. // Sleep for nSecs seconds under UNIX, do nothing under Windows
  675. // XView implementation according to the Heller manual
  676. void wxSleep(int nSecs)
  677. {
  678. }
  679.  
  680. // Consume all events until no more left
  681. void wxFlushEvents(void)
  682. {
  683. }
  684.  
  685. // Output a debug mess., in a system dependent fashion.
  686. void wxDebugMsg(char *fmt ...)
  687. {
  688.   va_list ap;
  689.   static char buffer[512];
  690.  
  691.   va_start(ap, fmt);
  692.  
  693.   wvsprintf(buffer,fmt,ap) ;
  694.   OutputDebugString(buffer) ;
  695.  
  696.   va_end(ap);
  697. }
  698. */
  699.  
  700. // Non-fatal error: pop up message box and (possibly) continue
  701. void wxError(char *msg, char *title)
  702. {
  703.   cerr << title << msg << "\n";
  704. }
  705.  
  706. // Fatal error: pop up message box and abort
  707. void wxFatalError(char *msg, char *title)
  708. {
  709.   cerr << title << msg << "\n";
  710.   exit(1);
  711. }
  712.  
  713.